package org.andy.dblock.manager.impl;

import java.sql.Connection;
import java.sql.SQLException;

import org.andy.dblock.entity.MethodLock;
import org.andy.dblock.manager.DataSourceManager;
import org.andy.dblock.manager.DbLockManager;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 数据库排他锁实现分布式锁<br>
 *
 * @author andy
 * @version V1.0
 * @date 18/2/8 上午12:30
 */
public class DbExclusiveLockManagerImpl implements DbLockManager {

    private static final Logger LOG = LoggerFactory.getLogger(DbLockManagerImpl.class);

    private static final QueryRunner QUERY_RUNNER = new QueryRunner();

    public static String selectSql
        = "select id,method_name as methodName, description, update_time as updateTime  from method_lock where "
        + "method_name = ? for update";

    @Override
    public boolean lock(String methodName) {
        DataSourceManager.beginTransaction();
        Connection conn = DataSourceManager.getConnection();

        while (true) {
            try {
                MethodLock methodLock = QUERY_RUNNER.query(conn, selectSql, new BeanHandler<>(MethodLock.class),
                    new Object[] {methodName});
                if (methodLock != null){
                    return true;
                }
            } catch (SQLException e) {
                LOG.error(e.getMessage());
            }
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void unLock(String methodName) {
        DataSourceManager.commitTeansaction();
    }
}
